home *** CD-ROM | disk | FTP | other *** search
- /* XList.cpp */
-
- #include "XList.hh"
-
-
- void
- CXNode::AddNext(XObject *inNewDatum)
- {
- CXNode *node = new CXNode(inNewDatum);
- node->mNext = mNext;
- mNext = node;
- }
-
- CXNode *
- CXNode::RemoveNext()
- {
- CXNode *node = mNext;
- mNext = mNext->mNext;
- return node;
- }
-
- XList::~XList()
- {
- Purge();
- }
-
- CXNode *
- XList::FindNode(XObject * inDatum) const
- {
- CXNode *node = mHead;
-
- for (node = mHead; node; node = node->Next())
- if (node->Datum() == inDatum)
- return node;
-
- return NULL;
- }
-
- void
- XList::Prepend(XObject * inNewDatum)
- {
- if (!mHead) mHead = mTail = new CXNode(inNewDatum);
- else {
- CXNode *head = new CXNode(inNewDatum);
- head->mNext = mHead;
- mHead = head;
- }
- }
-
- void
- XList::Append(XObject *inNewDatum)
- {
- if (!mHead) mHead = mTail = new CXNode(inNewDatum);
- else {
- #if 0
- CXNode *last = mHead;
- while (last->Next())
- last = last->Next();
- last = new CXNode(inNewDatum);
- mTail = last;
- #endif
- mTail->mNext = new CXNode(inNewDatum);
- mTail = mTail->mNext;
- }
- }
-
- XObject *
- XList::Behead()
- {
- if (!mHead) return NULL;
- CXNode *head = mHead;
- mHead = mHead->mNext;
- return head->Datum();
- }
-
- void
- XList::Remove(XObject *inVictim)
- {
- // Check for an empty list.
- if (!mHead) return;
-
- CXNode *pred = mHead;
-
- // Check for special case: match on first item.
- if (mHead->Datum() == inVictim) {
- mHead = mHead->Next();
- delete pred;
- return;
- }
- while (pred->Next()) { // List of one item stops here.
- if (pred->Next()->Datum() == inVictim) {
- delete pred->RemoveNext();
- return;
- }
- }
- // Couldn't find it.
- }
-
- void
- XList::Purge()
- {
- CXNode *node = mHead;
-
- // It is critical to reset mHead prior to deleting nodes, because it is
- // possible for a destructor to call autorelease(), which would attempt to
- // append a new node onto the list.
- // Actually, Append() would check mHead and conclude that there were nodes,
- // and add the new node to the end of the list, which would actually work,
- // if mTail was not the node being deleted.
- // More actually, mTail would be set to the new node, but the delete loop
- // would have already recorded a NULL for ondeck. A NULL mHead indicates an
- // empty list, in which case mTail is undefined, so correct code would not
- // subsequently refer to it. Therefore, any objects autoreleased by the last
- // node being deleted would be leaked. So reset mHead first!
-
- mHead = NULL;
-
- while (node) {
- CXNode *ondeck = node->Next();
- //XObject *victim = node->Datum();
- delete node;
- //victim->release();
- node = ondeck;
- }
- }
-